


void Circle::CollisionResponseWithLine(ManifoldPoint& point, float dt)
{
	float e = Elasticity; 
	////////////////////////////////////////////////////////////

	Circle* c1 = this;
	Line* l = (Line*)point.contactID1;
	////////////////////////////////////////////////////////////////////////////


	//----------------------
	if (l->GetPos(0).GetX() >= -4.0f && l->GetPos(0).GetX() < 3.9f &&
		l->GetPos(0).GetY() <= 12.0f && l->GetPos(0).GetY() >= 0.0f)  {
			
			if (l->getNormal().dot(c1->GetPos()-l->GetPos(0)) > 0.0f && m_game->activeRope())
				m_game->rope.addForce(Vector(0, -m_data->m_mass * 9.81f));
	}

	//----------------------


	double invDt = 1.0f / dt;

	Vector nn = point.contactNormal;

	Vector r1 = point.contactPoint - c1->GetPos();
	r1.Set(r1.GetX(), r1.GetY(), 0);
 
	// get all of relative normal velocity
	double relNv = ((c1->GetVel() + c1->GetAngularVel().cross(r1)).dot(nn));

	double vBias = 0.0f;
	if (point.t == -1.0f) {
		vBias = (point.contactPoint.GetZ()-0.0001f) * 0.2f  * invDt;
	}

	double velBias = relNv * Circle::Elasticity;
	double remove = relNv - vBias + velBias;// + dist * 200.0f;	


	
	double denom = 1.0f / c1->GetMass();

	//if (point.t != -1.0f) {
	
	denom = (1.0f / c1->GetMass() + 
	nn.dot(Vector((r1.cross(point.contactNormal)) / c1->GetInertia()).cross(r1)));  

	//}

	denom = 1.0 / denom;

	//// compute impulse
	double imp = remove * denom/*c1->GetMass()*/;
	 

	// sequential impulses

	double temp = point.impulse;
	point.impulse = min(point.impulse + imp, 0);
	imp = point.impulse - temp;

	
	//////////////

	// apply impulse
	
	Vector Vel = c1->GetVel() -  (float)imp * nn / c1->GetMass();
	c1->SetVel(Vel.GetX(), Vel.GetY());

	
	Vector w1_n = c1->GetAngularVel() - (r1.cross((float)imp*nn)) / c1->GetInertia();
	c1->SetAngularVel(w1_n);
	

	
	// ----------------------------------
	// F R I C T I O N ------------------
	// __________________________________
	bool bFriction = true;

	if (bFriction) {
		Vector t = nn.cross(Vector(0,0,1));

		denom = 
		(1.0f/c1->GetMass() +
		t.dot(Vector((r1.cross(t))/c1->GetInertia()).cross(r1))); 
	}
	denom = 1.0 / denom;

	Vector t = nn.cross(Vector(0,0,1));
	double vt = (c1->GetVel() + c1->GetAngularVel().cross(r1)).dot(t);
	double dPt = denom * (-vt);

	// sequential impulse
	double maxPt = Friction * point.impulse;

	double oldTangentImpulse = point.t_impulse;
	// clamp
	point.t_impulse = oldTangentImpulse + dPt;
	if (point.t_impulse < -maxPt)
		point.t_impulse = -maxPt;
	else if (point.t_impulse > maxPt)
		point.t_impulse = maxPt;

	dPt = point.t_impulse - oldTangentImpulse;
	 // /

	// Apply contact impulse
	Vector Pt = (float)dPt * t;


	Vector Vel0 = c1->GetVel() + Pt / c1->GetMass() ; 	
	c1->SetVel(Vel0.GetX(), Vel0.GetY());
	
	
	//if (point.t != -1.0f) {
	Vector angVel0 = c1->GetAngularVel() - (r1.cross(Pt)) / c1->GetInertia();
	c1->SetAngularVel(angVel0);
		
	//}

	point.responded = true;
}
